//package com.ninglz.bamboo.common.data.datascope;
//
//import com.baomidou.mybatisplus.core.conditions.Wrapper;
//import com.baomidou.mybatisplus.core.enums.SqlMethod;
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
//import com.baomidou.mybatisplus.core.metadata.TableInfo;
//import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
//import com.baomidou.mybatisplus.core.toolkit.*;
//import com.baomidou.mybatisplus.extension.service.IService;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
//import org.apache.ibatis.binding.MapperMethod;
//import org.apache.ibatis.logging.Log;
//import org.apache.ibatis.logging.LogFactory;
//import org.apache.ibatis.session.SqlSession;
//import org.mybatis.spring.SqlSessionUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.core.ResolvableType;
//import org.springframework.transaction.annotation.Transactional;
//import org.springframework.util.ClassUtils;
//import org.springframework.util.ReflectionUtils;
//
//import java.io.Serializable;
//import java.util.*;
//import java.util.function.BiConsumer;
//import java.util.function.Consumer;
//import java.util.function.Function;
//
///**
// * 继承mybatis-plus的IService
// * @param <T> 领域模型
// * @param <D> 领域模型对应的仓储对象
// * @param <M> 领域模型对应的Mapper
// */
//public class BambooBaseGatewayImpl<M extends BaseMapper<D>, T, D> implements BambooBaseGateway<T> {
//
//    protected Log log = LogFactory.getLog(getClass());
//
//    @Autowired
//    protected M baseMapper;
//
//    @Override
//    public M getBaseMapper() {
//        return baseMapper;
//    }
//
//    protected Class<T> entityClass = currentModelClass();
//
//    @Override
//    public Class<T> getEntityClass() {
//        return entityClass;
//    }
//
//    protected Class<T> mapperClass = currentMapperClass();
//
//    /**
//     * 判断数据库操作是否成功
//     *
//     * @param result 数据库操作返回影响条数
//     * @return boolean
//     * @deprecated 3.3.1
//     */
//    @Deprecated
//    protected boolean retBool(Integer result) {
//        return SqlHelper.retBool(result);
//    }
//
//    protected Class<T> currentMapperClass() {
//        return (Class<T>) this.getResolvableType().as(ServiceImpl.class).getGeneric(0).getType();
//    }
//
//    protected Class<T> currentModelClass() {
//        return (Class<T>) this.getResolvableType().as(ServiceImpl.class).getGeneric(1).getType();
//    }
//
//    /**
//     * @see ResolvableType
//     * @since 3.4.3
//     */
//    protected ResolvableType getResolvableType() {
//        return ResolvableType.forClass(com.baomidou.mybatisplus.core.toolkit.ClassUtils.getUserClass(getClass()));
//    }
//
//    /**
//     * 批量操作 SqlSession
//     *
//     * @deprecated 3.3.0
//     */
//    @Deprecated
//    protected SqlSession sqlSessionBatch() {
//        return SqlHelper.sqlSessionBatch(entityClass);
//    }
//
//    /**
//     * 释放sqlSession
//     *
//     * @param sqlSession session
//     * @deprecated 3.3.0
//     */
//    @Deprecated
//    protected void closeSqlSession(SqlSession sqlSession) {
//        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(entityClass));
//    }
//
//    /**
//     * 获取 SqlStatement
//     *
//     * @param sqlMethod ignore
//     * @return ignore
//     * @see #getSqlStatement(SqlMethod)
//     * @deprecated 3.4.0
//     */
//    @Deprecated
//    protected String sqlStatement(SqlMethod sqlMethod) {
//        return SqlHelper.table(entityClass).getSqlStatement(sqlMethod.getMethod());
//    }
//
//    /**
//     * 批量插入
//     *
//     * @param entityList ignore
//     * @param batchSize  ignore
//     * @return ignore
//     */
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean saveBatch(Collection<T> entityList, int batchSize) {
//        String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
//        return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
//    }
//
//    /**
//     * 获取mapperStatementId
//     *
//     * @param sqlMethod 方法名
//     * @return 命名id
//     * @since 3.4.0
//     */
//    protected String getSqlStatement(SqlMethod sqlMethod) {
//        return SqlHelper.getSqlStatement(mapperClass, sqlMethod);
//    }
//
//    /**
//     * TableId 注解存在更新记录，否插入一条记录
//     *
//     * @param entity 实体对象
//     * @return boolean
//     */
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean saveOrUpdate(T entity) {
//        if (null != entity) {
//            TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
//            Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
//            String keyProperty = tableInfo.getKeyProperty();
//            Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
//            Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());
//            return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal)) ? save(entity) : updateById(entity);
//        }
//        return false;
//    }
//
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
//        TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
//        Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
//        String keyProperty = tableInfo.getKeyProperty();
//        Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
//        return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
//            Object idVal = ReflectionKit.getFieldValue(entity, keyProperty);
//            return StringUtils.checkValNull(idVal)
//                    || CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
//        }, (sqlSession, entity) -> {
//            MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
//            param.put(Constants.ENTITY, entity);
//            sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
//        });
//    }
//
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
//        String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
//        return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
//            MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
//            param.put(Constants.ENTITY, entity);
//            sqlSession.update(sqlStatement, param);
//        });
//    }
//
//    @Override
//    public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
//        return null;
////        if (throwEx) {
////            return baseMapper.selectOne(queryWrapper);
////        }
////        return SqlHelper.getObject(log, baseMapper.selectList(queryWrapper));
//    }
//
//    @Override
//    public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
//        return null;
////        return SqlHelper.getObject(log, baseMapper.selectMaps(queryWrapper));
//    }
//
//    @Override
//    public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
//        return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
//    }
//
//    /**
//     * 执行批量操作
//     *
//     * @param consumer consumer
//     * @since 3.3.0
//     * @deprecated 3.3.1 后面我打算移除掉 {@link #executeBatch(Collection, int, BiConsumer)} }.
//     */
//    @Deprecated
//    protected boolean executeBatch(Consumer<SqlSession> consumer) {
//        return SqlHelper.executeBatch(this.entityClass, this.log, consumer);
//    }
//
//    /**
//     * 执行批量操作
//     *
//     * @param list      数据集合
//     * @param batchSize 批量大小
//     * @param consumer  执行方法
//     * @param <E>       泛型
//     * @return 操作结果
//     * @since 3.3.1
//     */
//    protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
//        return SqlHelper.executeBatch(this.entityClass, this.log, list, batchSize, consumer);
//    }
//
//    /**
//     * 执行批量操作（默认批次提交数量{@link IService#DEFAULT_BATCH_SIZE}）
//     *
//     * @param list     数据集合
//     * @param consumer 执行方法
//     * @param <E>      泛型
//     * @return 操作结果
//     * @since 3.3.1
//     */
//    protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) {
//        return executeBatch(list, DEFAULT_BATCH_SIZE, consumer);
//    }
//
//    private static <D> D instantiateFactory(String factoryImplementationName, Class<D> factoryType, ClassLoader classLoader) {
//        try {
//            Class<?> factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
//            if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
//                throw new IllegalArgumentException(
//                        "Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
//            }
//            return (D) ReflectionUtils.accessibleConstructor(factoryImplementationClass).newInstance();
//        }
//        catch (Throwable ex) {
//            throw new IllegalArgumentException(
//                    "Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]",
//                    ex);
//        }
//    }
//}
